home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / comm / net / tf02.lha / TinyFugue / tf-lib / complete.tf < prev    next >
Text File  |  1995-08-12  |  8KB  |  253 lines

  1. ;;;; Completion.
  2. ;; This allows you to type part of a word, hit a special key, and have
  3. ;; the rest of the word filled in for you automagically.  ESC TAB attempts
  4. ;; to complete based on context, or from a user defined list of words;
  5. ;; a few other bindings will do more explicit completions.
  6. ;;
  7. ;; To use:  /load this file, and optionally store a list of words in
  8. ;; %{completion_list}.  For example, add this to your ~/.tfrc file:
  9. ;;
  10. ;;    /load complete.tf
  11. ;;    /set completion_list=Hawkeye TinyFugue ftp.tcp.com
  12. ;;
  13. ;; Completion keys:
  14. ;;
  15. ;; ESC TAB    complete from context, input history, or %{completion_list}.
  16. ;; ESC ;    complete from %{completion_list}.
  17. ;; ESC i    complete from input history.
  18. ;; ESC /    filename completion.
  19. ;; ESC @    hostname completion.
  20. ;; ESC %    variable name completion.
  21. ;; ESC $    macro name completion.
  22. ;; ESC ^W    world name completion.
  23.  
  24. ;; By "from context", I mean it will look for patterns and decide which
  25. ;; type of completion to use.  For example, if the line begins with "/load",
  26. ;; it will use filename completion; if the word begins with "%" or "%{", it
  27. ;; will use variable name completion; etc.
  28.  
  29. ;; Optional user extensions.
  30. ;; To add your own completion, write a macro with a name like complete_foo
  31. ;; which takes the partial word as an argument, and calls /_complete_from_list
  32. ;; with the partial word and a list of possible matches.  Then bind a key
  33. ;; sequence that calls "/complete foo", and/or add a context
  34. ;; sensitive call in "/complete_context".
  35.  
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37.  
  38. /~loaded completion.tf
  39.  
  40. /require lisp.tf
  41.  
  42. /def -ib'^[^I'    = /complete
  43. /def -ib'^[;'    = /complete user_defined
  44. /def -ib'^[i'    = /complete input_history
  45. /def -ib'^[/'    = /complete filename
  46. /def -ib'^[@'    = /complete hostname
  47. /def -ib'^[%'    = /complete variable
  48. /def -ib'^[$'    = /complete macroname
  49. /def -ib'^[^W'    = /complete worldname
  50.  
  51. ; /def -ib'^[~'    = /complete playername  (not implemented)
  52. ; /def -ib'^[!'    = /complete command     (not implemented)
  53.  
  54. ;; /complete_playername is difficult to do correctly because of mud delays,
  55. ;; and is not portable to different muds, so it is not implemented here.
  56.  
  57.  
  58. /def -i complete = \
  59.     /complete_%{1-context} $(/last $[kbhead()])
  60.  
  61.  
  62. ;; /_complete_from_list <word> <list...>
  63. ;; <word> is the partial word to be completed.
  64. ;; <list> is a list of possible matches.
  65. ;; If <word> matches exactly one member of <list>, that member will be
  66. ;; inserted in the input buffer.  If multiple matches are found, the
  67. ;; longest common prefix will be inserted, and a list of matches will
  68. ;; be displayed.  If no matches are found, it simply beeps.
  69. ;; If exactly one match was found, %{_completion_suffix} or a space
  70. ;; will be appended to the completed word.
  71. ;; If the local variable %{_need_unique} is true, the list will be run
  72. ;; through /unique.
  73.  
  74. /def -i _complete_from_list = \
  75.     /let prefix=%1%;\
  76.     /shift%;\
  77.     /let len=$[strlen(prefix)]%;\
  78.     /let match=%;\
  79. ;
  80. ;   scan list for words which start with prefix.
  81.     /while ({#}) \
  82.         /if ( strncmp({1}, prefix, len) == 0 ) \
  83.             /let match=%{match} %{1}%;\
  84.         /endif%;\
  85.         /shift%;\
  86.     /done%;\
  87. ;
  88.     /if (_need_unique) \
  89. ;       Remove duplicates (and strip leading space)
  90.         /let match=$(/unique %{match})%;\
  91.     /else \
  92. ;       Strip leading space
  93.         /let match=$(/echo - %{match})%;\
  94.     /endif%;\
  95. ;
  96.     /if ( match =~ "" ) \
  97. ;       No match was found.
  98.         /beep 1%;\
  99.     /elseif ( match !/ "{*}" ) \
  100. ;       Multiple matches were found.  Use longest common prefix.
  101.         /beep 1%;\
  102.         /let common=$(/common_prefix %{len} %{match})%;\
  103.         /test input(substr(common, len))%;\
  104.         /echo - %{match}%;\
  105.     /else \
  106. ;       Exactly one match was found.
  107.         /test match := strcat(match, _completion_suffix)%;\
  108.         /if ( match =/ "*[A-Za-z0-9_]" ) \
  109.             /test match := strcat(match, " ")%;\
  110.         /endif%;\
  111.         /test input(substr(match, len))%;\
  112.     /endif%;\
  113. ;   Just to be safe
  114.     /unset _completion_suffix%;\
  115.     /unset _need_unique
  116.  
  117.  
  118. /def -i complete_user_defined = \
  119.     /_complete_from_list %1 %completion_list
  120.  
  121. /def -i ~input_history_list = \
  122.     /let input=$(/recall -i #1)%;\
  123.     /recall -i 1-$[substr(input, 0, strchr(input, ":")) - 1]
  124.  
  125. /def -i complete_input_history = \
  126.     /let _need_unique=1%;\
  127.     /_complete_from_list %1 $(/~input_history_list)
  128.  
  129. /def -i complete_dynamic = \
  130.     /let _need_unique=1%;\
  131.     /_complete_from_list %1 %completion_list $(/~input_history_list)
  132.  
  133.  
  134. /def -i complete_filename = \
  135.     /quote -S /_complete_from_list %1 !\
  136.         echo `/bin/ls -dq %1* 2>/dev/null | \
  137.             while read f; do \ test -d $$f && echo $$f/ || echo $$f; done`
  138.  
  139.  
  140. /def -i complete_hostname = \
  141.     /let _need_unique=1%;\
  142.     /let pf=$[substr({1}, strrchr({1}, "@") + 1)]%;\
  143.     /quote -S /_complete_from_list %{pf} !\
  144.        echo `cat /etc/hosts %HOME/etc/hosts 2>/dev/null | \
  145.           sed -n '/^[^#].*[     ][     ]*\\\\(%{pf}[^     ]*\\\\).*/s//\\\\1/p'`
  146.  
  147.  
  148. /def -i complete_variable = \
  149.     /let part=$[substr({1}, strrchr({1}, '%') + 1)]%;\
  150.     /if ( strncmp(part, '{', 1) == 0 ) \
  151.         /let part=$[substr(part, 1)]%;\
  152.         /let _completion_suffix=}%;\
  153.     /endif%;\
  154.     /_complete_from_list %part \
  155.         $(/quote -S /_complete_variable `/set%%;/setenv)
  156.  
  157. /def -i _complete_variable = \
  158.     /let name=%-1%;\
  159.     /test echo(substr(name, 0, strchr(name, '=')))%;\
  160.  
  161.  
  162. /def -i complete_macroname = \
  163.     /let word=%1%;\
  164.     /let i=$[strrchr({1}, '$')]%;\
  165.     /if ( i >= 0 ) \
  166.         /if ( substr(word, i+1, 1) =~ '{' ) \
  167.             /test i:= i + 1%;\
  168.             /let _completion_suffix=}%;\
  169.         /endif%;\
  170.         /let word=$[substr(word, i+1)]%;\
  171.     /elseif ( strncmp(word, '/', 1) == 0 ) \
  172.         /let word=$[substr(word, 1)]%;\
  173.     /endif%;\
  174.     /_complete_from_list %{word} $(/quote -S /last `/list -s -i - %{word}*)
  175.  
  176.  
  177. /def -i complete_worldname = \
  178.     /_complete_from_list %1 $(/quote -S /_complete_worldname `/listworlds %{1}*)
  179.  
  180. /def -i _complete_worldname = \
  181.     /shift $[{2} =/ "-T*"]%;\
  182.     /echo - %{2}
  183.  
  184.  
  185. ;; /complete_context <word>
  186. ;; Uses context to determine which completion macro to use.
  187.  
  188. /def -i complete_context = \
  189.     /let head=$[kbhead()]%;\
  190.     /let word=%1%;\
  191.     /if ( strchr(word, "@") >= 0 ) \
  192.         /complete_hostname %1%;\
  193.     /elseif ( strchr(word, "%%") >= 0 ) \
  194.         /complete_variable %1%;\
  195.     /elseif ( strchr(word, "$$") >= 0 ) \
  196.         /complete_macroname %1%;\
  197. ;   /elseif ( head =/ "{/*}" ) \
  198. ;       /complete_command %1%;\
  199.     /elseif ( head =/ "{/*}" ) \
  200.         /complete_macroname %1%;\
  201.     /elseif ( regmatch("-w(.+)$$", head) ) \
  202.         /complete_worldname %P1%;\
  203.     /elseif ( head =/ "*{/[sl]et|/setenv|/unset} {*}" ) \
  204.         /complete_variable %1%;\
  205.     /elseif ( head =/ "*{/load*|/save*|/lcd|/cd|/log} {*}" ) \
  206.         /complete_filename %1%;\
  207.     /elseif ( head =/ "*{/def|/edit|/reedit} {*}" ) \
  208.         /complete_macroname %1%;\
  209. ;   /elseif ( head =/ "*{wh|page|tel*|kill} {*}" ) \
  210. ;       /complete_playername %1%;\
  211.     /elseif ( regmatch("/quote .*'(\"?)(.+)$$", head) ) \
  212.         /let completion_suffix=%P1%;\
  213.         /complete_filename %P2%;\
  214. ;   /elseif ( regmatch("/quote .*`(\"?)(.+)$$", head) ) \
  215. ;       /let completion_suffix=%P1%;\
  216. ;       /complete_command %P2%;\
  217.     /elseif ( regmatch("/quote .*`(\"?)(.+)$$", head) ) \
  218.         /let completion_suffix=%P1%;\
  219.         /complete_macroname %P2%;\
  220.     /elseif ( head =/ "*{/world|/connect|/fg} {*}" ) \
  221.         /complete_worldname %1%;\
  222.     /elseif ( head =/ "*{/telnet} {*}" ) \
  223.         /complete_hostname %1%;\
  224.     /elseif ( head =/ "*/quote *!*" ) \
  225.         /complete_filename %1%;\
  226.     /elseif ( head =/ "*{/test|/expr} *" ) \
  227.         /complete_variable %1%;\
  228.     /elseif ( head =/ "*{*/*|.*|tiny.*}" ) \
  229.         /complete_filename %1%;\
  230.     /else \
  231.         /complete_dynamic %1%;\
  232.     /endif
  233.  
  234.  
  235. ;;; /common_prefix <min> <list>...
  236. ;; prints the common prefix shared by each word in <list>, assuming at least
  237. ;; first <min> chars are already known to be shared.
  238.  
  239. /def -i common_prefix = \
  240.     /let min=%1%;\
  241.     /shift%;\
  242.     /let prefix=%1%;\
  243.     /let len=$[strlen(prefix)]%;\
  244.     /while /shift%; /test {#} & len > min%; /do \
  245.         /let i=%min%;\
  246.         /while ( i < len & strncmp(prefix, {1}, i+1) == 0 ) \
  247.             /let i=$[i + 1]%;\
  248.         /done%;\
  249.         /let len=%i%;\
  250.     /done%;\
  251.     /echo - $[substr(prefix, 0, len)]
  252.  
  253.